namespace SimpleWebServices.Configuration
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Web.Mvc;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;
    using SimpleWebServices.Models;

    [XmlRoot("handler")]
    public sealed class SubmissionHandlerSetting : IXmlSerializable
    {
        public SubmissionHandlerSetting()
        {
            this.Processors = new Collection<SubmissionProcessorSetting>();
        }

        public string Name
        {
            get;
            set;
        }

        public IList<SubmissionProcessorSetting> Processors
        {
            get;
            private set;
        }
        
        public ActionResult Process(FormSubmission submission)
        {
            if (null == submission)
            {
                throw new ArgumentNullException("submission");
            }

            ActionResult result = null;

            if (0 != this.Processors.Count)
            {
                foreach (var processor in this.Processors)
                {
                    result = processor.Process(submission);
                    if (null != result)
                    {
                        break;
                    }
                }
            }

            return result;
        }

        XmlSchema IXmlSerializable.GetSchema()
        {
            throw new NotSupportedException();
        }

        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            if (null == reader)
            {
                throw new ArgumentNullException("reader");
            }

            this.Name = reader.GetAttribute("name");

            if (reader.IsEmptyElement)
            {
                reader.Read();
            }
            else
            {
                string name = reader.Name;
                reader.Read();
                while (true)
                {
                    if (XmlNodeType.None == reader.NodeType)
                    {
                        break;
                    }
                    else if (XmlNodeType.EndElement == reader.NodeType && reader.Name == name)
                    {
                        reader.Read();
                        break;
                    }
                    else if ("processor".Equals(reader.Name, StringComparison.OrdinalIgnoreCase))
                    {
                        this.Processors.Add(reader.ReadOuterXml().Deserialize<SubmissionProcessorSetting>());
                    }
                    else
                    {
                        reader.Read();
                    }
                }
            }
        }

        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            if (null == writer)
            {
                throw new ArgumentNullException("writer");
            }

            if (null != this.Name)
            {
                writer.WriteAttributeString("name", this.Name);
            }

            foreach (SubmissionProcessorSetting setting in this.Processors)
            {
                writer.WriteRaw(setting.Serialize().CreateNavigator().OuterXml);
            }
        }
    }
}